﻿using System;
using System.Collections.Generic;
using System.Threading;
using MDK.Device.Components;
using MDK.Device.Devices;

namespace MDK.Device
{
    public class Back2Flow
    {
        public bool IsCompleted { get; private set; }

        private SystemModel SysModel { get; }
        public PositionModel PosModel { get; }

        public Back2Flow()
        {
            SysModel = SystemModel.Instance;
            PosModel = PositionModel.Load();
        }

        /// <summary>
        /// 载条转生化盘
        /// </summary>
        public void StartStripToBiochemicalDial()
        {
            SysModel.Back2.Device.ClearError();
            SysModel.Back2.Device.SwitchAutoMode();
            SysModel.Back2.X.Speed = 1000;
            SysModel.Back2.Y.Speed = 1000;
            IsCompleted = false;
            ThreadPool.QueueUserWorkItem(arg =>
            {
                var hole = 0;
                for (int i = 0; i < 9; i++)
                {
                    if (!SysModel.Back2.CarrierSensors[i].IsActive()) continue;

                    for (int j = 0; j < 16; j++)
                    {
                        SysModel.Back2.Finger.TurnOn();

                        SysModel.Back2.FingerRotator.Rotate(_stripDragAngleOffset, RotateRefLocations.Zero);

                        SysModel.Back2.SZ.Goto(0);
                        SysModel.Back2.SZ.WaitCompleted();

                        SysModel.Back2.X.Goto(PosModel.Back2StripPositions[i].GetHoleX(j));
                        SysModel.Back2.Y.Goto(PosModel.Back2StripPositions[i].GetHoleY(j));
                        SysModel.Back2.FingerRotator.WaitCompleted();
                        SysModel.Back2.X.WaitCompleted();
                        SysModel.Back2.Y.WaitCompleted();

                        SysModel.Back2.SZ.Goto(PosModel.Back2StripPositions[i].TubeSZ);
                        SysModel.Back2.SZ.WaitCompleted();
                        SysModel.Back2.Finger.TurnOff();
                        SysModel.Back2.SZ.Goto(0);
                        SysModel.Back2.FingerRotator.Rotate((hole % 55) * 360 / 55 + _barcodeAlignAngleOffset[hole / 55], RotateRefLocations.Barcode);

                        SysModel.Back2.SZ.WaitCompleted();

                        if (hole >= 55)
                        {
                            SysModel.Back2.X.Goto(PosModel.Back2TempPosition.X);
                            SysModel.Back2.Y.Goto(PosModel.Back2TempPosition.Y);
                            SysModel.Back2.FingerRotator.WaitCompleted();
                            SysModel.Back2.X.WaitCompleted();
                            SysModel.Back2.Y.WaitCompleted();

                            SysModel.Back2.SZ.Goto(PosModel.Back2TempPosition.TubeSZ);
                            SysModel.Back2.SZ.WaitCompleted();

                            SysModel.Back2.Finger.TurnOn();

                            SysModel.Back2.FingerRotator.Rotate(OptimizeAngle((hole % 55) * 360 / 55 + _dialDragAngleOffset), RotateRefLocations.Zero);
                            SysModel.Back2.FingerRotator.WaitCompleted();

                            SysModel.Back2.Finger.TurnOff();

                            SysModel.Back2.SZ.Goto(0);
                            SysModel.Back2.SZ.WaitCompleted();
                        }
                        SysModel.Back2.X.Goto(PosModel.BiochemicalDialPosition.GetHoleX(hole));
                        SysModel.Back2.Y.Goto(PosModel.BiochemicalDialPosition.GetHoleY(hole));
                        if (hole < 55)
                        {
                            SysModel.Back2.FingerRotator.WaitCompleted();
                        }
                        SysModel.Back2.X.WaitCompleted();
                        SysModel.Back2.Y.WaitCompleted();

                        SysModel.Back2.SZ.Goto(PosModel.BiochemicalDialPosition.TubeSZ);
                        SysModel.Back2.SZ.WaitCompleted();

                        hole++;
                        if (hole >= 110)
                        {
                            break;
                        }
                    }
                    if (hole >= 110)
                    {
                        break;
                    }
                }

                SysModel.Back2.SZ.Goto(0);
                SysModel.Back2.SZ.WaitCompleted();
                SysModel.Back2.Y.Goto(0);
                SysModel.Back2.X.Goto(0);
                SysModel.Back2.Y.WaitCompleted();
                SysModel.Back2.X.WaitCompleted();

                IsCompleted = true;
            });
        }

        /// <summary>
        /// 生化盘转96孔
        /// </summary>
        public void StartBiochemicalDialTo96Hole()
        {
            IsCompleted = false;
            SysModel.Back2.Device.ClearError();
            SysModel.Back2.Device.SwitchAutoMode();
            SysModel.Back2.X.Speed = 1000;
            SysModel.Back2.Y.Speed = 1000;
            ThreadPool.QueueUserWorkItem(arg =>
            {
                for (int hole = 0; hole < 96; hole++)
                {
                    SysModel.Back2.Finger.TurnOn();

                    if (hole >= 55)
                    {
                        SysModel.Back2.FingerRotator.Rotate(OptimizeAngle((hole % 55) * 360 / 55 + _dialDragAngleOffset), RotateRefLocations.Zero);
                    }
                    SysModel.Back2.SZ.Goto(0);
                    SysModel.Back2.SZ.WaitCompleted();

                    SysModel.Back2.X.Goto(PosModel.BiochemicalDialPosition.GetHoleX(hole));
                    SysModel.Back2.Y.Goto(PosModel.BiochemicalDialPosition.GetHoleY(hole));
                    if (hole >= 55)
                    {
                        SysModel.Back2.FingerRotator.WaitCompleted();
                    }
                    SysModel.Back2.X.WaitCompleted();
                    SysModel.Back2.Y.WaitCompleted();

                    SysModel.Back2.SZ.Goto(PosModel.BiochemicalDialPosition.TubeSZ);
                    SysModel.Back2.SZ.WaitCompleted();
                    SysModel.Back2.Finger.TurnOff();

                    SysModel.Back2.SZ.Goto(0);

                    SysModel.Back2.FingerRotator.Rotate(_96HoleDragAngleOffset, RotateRefLocations.Zero);

                    SysModel.Back2.SZ.WaitCompleted();

                    SysModel.Back2.X.Goto(PosModel.Hole96Position.GetHoleX(hole));
                    SysModel.Back2.Y.Goto(PosModel.Hole96Position.GetHoleY(hole));
                    SysModel.Back2.FingerRotator.WaitCompleted();
                    SysModel.Back2.X.WaitCompleted();
                    SysModel.Back2.Y.WaitCompleted();

                    SysModel.Back2.SZ.Goto(PosModel.Hole96Position.TubeSZ);
                    SysModel.Back2.SZ.WaitCompleted();
                }

                SysModel.Back2.SZ.Goto(0);
                SysModel.Back2.SZ.WaitCompleted();
                SysModel.Back2.Y.Goto(0);
                SysModel.Back2.X.Goto(0);
                SysModel.Back2.Y.WaitCompleted();
                SysModel.Back2.X.WaitCompleted();

                IsCompleted = true;
            });
        }

        private double[] _barcodeAlignAngleOffset = {0, 170};


        private double _dialDragAngleOffset = 25;
        private double _96HoleDragAngleOffset = 0;
        private double _stripDragAngleOffset = 0;

        private double OptimizeAngle(double angle)
        {
            angle %= 360;
            angle = angle > 180 ? angle - 180 : angle;
            // return angle < 90 ? angle : angle - 180;
            return angle;
        }
    }
}